﻿using System;
using System.Collections;
using System.Collections.Generic;
using MagicKey.Components.Database;
using MagicKey.Factory;
using MagicKey.Interfaces;

namespace MagicKey.Components.UserManager
{
    public class UserManager : IUserManager
    {

        #region Enum

        /// <summary>
        /// The following enumeration defines the possible roles of an enrolled user in the college()university context.
        /// </summary>
        private enum Role
        {
            Student = 1,
            Professor = 2,
            Employee = 3,
            Guest = 4
        };

        #endregion Enum

        #region Fields

        /// <summary>
        /// The list with the names of all enrolled users.
        /// </summary>
        private List<string> _usernames;

        /// <summary>
        /// The list with instances of enrolled users.
        /// </summary>
        private List<User> _users;
        
        private static readonly IDatabase Database = new MagicDatabase();

        #endregion Fields

        #region Constructors

        public UserManager()
        {
            this._usernames = new List<string>();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets and sets property of the usernames field.
        /// </summary>
        public List<string> Usernames
        {
            get
            {
                return _usernames;
            }

            set
            {
                _usernames = value;
            }
        }

        /// <summary>
        /// Gets and sets property of the users field.
        /// </summary>
        public List<User> Users
        {
            get
            {
                return _users;
            }

            set
            {
                _users = value;
            }
        }

        #endregion Properties

        #region Methods

        public void LoadAllUsers()
        {
            this._usernames = new List<string>();

            IMagicKey iMagicKey = MagicKeyFactory.GetInstance().GetMagicKeyInterface();

            this._users = iMagicKey.GetDatabase().LoadAllUsers();
        }

        /// <summary>
        /// Gets the name of an user from the list of all enrolled users.
        /// </summary>
        /// <param name="username">The name of the new user.</param>
        public User GetUser(String username)
        {
            User userToReturn = null;

            if (this._usernames != null && !username.Equals(string.Empty))
            {
                foreach (User user in _users)
                {
                    if (user.Name.Equals(username))
                    {
                        userToReturn = user;
                        break;
                    }
                }
            }

            return userToReturn;
        }

        public void AddUser(String username)
        {

            if (this._usernames == null)
            {
                this._usernames = new List<string>();
            }
            this._usernames.Add(username);
        }

        public bool AddUser(string username, string password, string salt, string role, string publicKey,
            string privateKey)
        {
            this.AddUser(username);

            if (this._users == null)
            {
                this._users = new List<User>();
            }

            var newUser = new User()
            {
                EncryptedPassword = password,
                Name = username,
                Salt = salt,
                Role = role,
                PrivateKey = privateKey,
                PublicKey = publicKey
            };

            this._users.Add(newUser);
            Database.InsertUser(newUser.Name, newUser.EncryptedPassword, newUser.Salt, newUser.PublicKey,
                newUser.PrivateKey, GetRoleId(newUser.Role));

            return true;
        }

        /// <summary>
        /// Deletes the name of an user from the list of all enrolled users.
        /// </summary>
        /// <param name="username">The name of the user to be deleted.</param>
        public void DeleteUser(String username)
        {
            _usernames.Remove(username);
            // this._database = new MagicDatabase();
            // this._database;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public int GetRoleId(string role)
        {
            int roleId = -1, count = 0;
            const int roleCount = 4;

            while (roleId == -1 && count < roleCount)
            {
                if (role.ToLower().Equals(Role.Student.ToString().ToLower()))
                {
                    roleId = 1;
                }
                if (roleId == -1 && role.ToLower().Equals(Role.Professor.ToString().ToLower()))
                {
                    roleId = 2;
                }
                if (roleId == -1 && role.ToLower().Equals(Role.Employee.ToString().ToLower()))
                {
                    roleId = 3;
                }
                if (roleId == -1 && role.ToLower().Equals(Role.Guest.ToString().ToLower()))
                {
                    roleId = 4;
                }
                count++;
            }

            return roleId;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public string GetUserSymetricKey(string username)
        {
            return Database.LoadParameterUser("symetricKey", username);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public string GetOwnerName(string path)
        {
            return Database.GetOwnerName(path);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public string GetPrivateKeyEncrypted(string username)
        {
            return Database.LoadParameterUser("privateKey", username);
        }

        public string GetPublicKey(string username)
        {
            return Database.LoadParameterUser("publicKey", username);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public string GetSalt(string username)
        {
            return Database.LoadParameterUser("salt", username);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public string GetHashedPassword(string username)
        {
            return Database.LoadParameterUser("password", username);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
         public string GetSymetricKey(string username)
        {
            return Database.LoadParameterUser("symetricKey", username);
        }

        public int InsertUserFile(string pathOnServer, int ownerId)
        {
            return Database.InsertFile(pathOnServer, ownerId);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="selectedFile"></param>
        /// <returns></returns>
        public int GetFileId(string selectedFile)
        {
            return  Database.GetFileId(selectedFile);
        }

        #endregion Methods
    }
}
